package com.pt.pok;

import com.pt.pok.model.PokerCommand;

/**
 * @author Roman.Ivanov@playtech.com, Andrey.Panfilov@playtech.com
 * @date 1/23/12
 *       <p/>
 *       Dispatcher is responsible for giving protocol message to corresponding handler and choosing correct
 *       protocol marshaller for domain command
 *       <p/>
 *       P - protocol formatted message
 */
public interface Dispatcher<P> {

    /**
     * Takes domain command and gives back protocol formatted message
     * 
     * @param pokerCommand - domain command
     * @return protocol specific formatted data
     */
    P convert(PokerCommand pokerCommand);

    /**
     * Takes protocol formatted message and returns domain model object
     * 
     * @param classId class id {@link com.pt.pok.model.ClassIds}
     * @param protocolMessage protocol formatted data
     * @return domain model object
     * @throws GeneralProxyException in case of any troubles
     */
    PokerCommand handleDirect(int classId, P protocolMessage)
        throws GeneralProxyException;

    /**
     * Takes any protocol message data with class id, converts to concrete domain command and notifies
     * listeners
     * 
     * @param classId class id {@link com.pt.pok.model.ClassIds}
     * @param protocolMessage protocol formatted data
     * @throws GeneralProxyException in case of any problems
     */
    void handle(int classId, P protocolMessage)
        throws GeneralProxyException;

    /**
     * Register command handler
     * 
     * @param classId class id {@link com.pt.pok.model.ClassIds}
     * @param commandHandler command handler {@link com.pt.pok.CommandHandler}
     */
    void registerHandler(int classId, CommandHandler<P> commandHandler);

    /**
     * Add specific command marshaller
     * 
     * @param classId class id {@link com.pt.pok.model.ClassIds}
     * @param protocolMarshaller protocol command marshaller
     */
    void registerMarshaller(int classId, ProtocolMarshaller<P> protocolMarshaller);

    /**
     * Remove specific command handler
     * 
     * @param classId class id {@link com.pt.pok.model.ClassIds}
     */
    void unRegisterHandler(int classId);

    /**
     * Remove specific command marshaller
     * 
     * @param classId class id {@link com.pt.pok.model.ClassIds}
     */
    void unRegisterMarshaller(int classId);

    void addCommandListener(CommandListener commandListener);

    void removeCommandListener(CommandListener commandListener);

}
